// TestingProject.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <iterator>

#define BOOST_TEST_MODULE mytest

#include <algorithm>
#include <boost/test/unit_test.hpp>

using std::cin;
int add(int lhs, int rhs)
{
	return lhs + rhs;
}

/*
	------------------------------------------------------------------------------------------------------
			\\following this link	
			http://www.boost.org/doc/libs/1_51_0/libs/test/doc/html/tutorials/hello-the-testing-world.html
	------------------------------------------------------------------------------------------------------

*/

BOOST_AUTO_TEST_CASE(universeinorder)
{
	int a = 4;
	int b = 4;
	BOOST_CHECK(a == 4 && b == 4);
	BOOST_CHECK(add(2,2) == 5);
	BOOST_CHECK(add(2, 2) == 4);

	
	//BOOST_CHECK--->continues on an error
	//BOOST_REQUIRE--->throws an error
	//BOOST_ERROR--->continues on error
	//BOOST_CHECK_MESSAGE--->continues on error and produces a msg on screen
	//BOOST_CHECK_EQUAL--->continues on error
	
	
}

#include "..\RayTracing\RGBColor.h"

/*
	--------------------------------------
			Testing RGBColor Class
	--------------------------------------
*/
BOOST_AUTO_TEST_CASE(TestingRgbcolor)
{
	RGBColor color = RGBColor(0, 0, 0);
	BOOST_CHECK(color.r == 0 && color.g == 0 && color.b == 1);
	
}

#include "..\RayTracing\Point3D.h"

/*
	--------------------------------------
			Testing Vector Class
	--------------------------------------
*/
BOOST_AUTO_TEST_CASE(TestingVector)
{
	Point3D vectorTest = Point3D();
	BOOST_CHECK_EQUAL(vectorTest != 0, false);

	vectorTest = Point3D(0, 0, 0) + Point3D(1, 1, 1);


	
	
}

/*
	--------------------------------------
			Testing Sampler
	--------------------------------------
*/


BOOST_AUTO_TEST_CASE(TestingSampler)
{
	//Vector3D vector = Vector3D();
	//BOOST_CHECK(vector.x == 0 && vector.y == 0 && vector.z == 0 );

}

/*
	--------------------------------------
		Testing Peer neighbour handling
	--------------------------------------
*/

//#include "Peer.h"
//
//
//BOOST_AUTO_TEST_CASE(TestingPeerClass)
//{
//	Peer *testingPeer = new Peer("rtt");
//	std::string inputNeighbours = "11223-127.0.0.1|21112;112356-124.0.0.12|2115;11223-127.0.0.1|21112;";
//	testingPeer->AddNewNeighbours(inputNeighbours);
//	/*testing neighbours size == 2*/
//	BOOST_CHECK(testingPeer->neighbors.size() == 2);
//	std::string toFind = "127.0.0.1|21112";
//	int loc = 0;
//	BOOST_CHECK(testingPeer->FindNeighbour(RakNet::SystemAddress(toFind.c_str()),loc) == true);
//	testingPeer->RemoveNeighbour(loc);
//	BOOST_CHECK(testingPeer->FindNeighbour(RakNet::SystemAddress(toFind.c_str()), loc) == false);
//
//	BOOST_CHECK(testingPeer->GetCurrentLogicalTime() == 0);
//	testingPeer->IncrementLogicalTime();
//	BOOST_CHECK(testingPeer->GetCurrentLogicalTime() == 1);
//
//	
//	Neighbour randomNeighbor;
//	randomNeighbor = testingPeer->GetRandomNeighbour();
//	//BOOST_CHECK(randomNeighbor.address != NULL);
//
//	testingPeer->RemoveNeighbour("124.0.0.12|2115");
//	BOOST_CHECK(testingPeer->FindNeighbour(RakNet::SystemAddress(string("124.0.0.12|2115").c_str()), loc) == false);
//
//	inputNeighbours = "11223-127.0.0.1|21112;112356-124.0.0.12|2115;11223-127.0.0.1|21112;114545-129.0.0.2|45669;1129-189.168.2.1|44568;";
//	testingPeer->AddNewNeighbours(inputNeighbours);
//	//sort 
//	for (int index = 0; index < testingPeer->neighbors.size(); index++)
//	{
//		testingPeer->neighbors[index].UpdateLogicalTime(index);
//	}
//
//	testingPeer->SortCache();
//	
//	int previous = 0, current = 0;
//
//	for (int index = 0; index < testingPeer->neighbors.size(); index++)
//	{
//		previous = index == 0 ? 0 : testingPeer->neighbors[index - 1].lastConnection;
//		current = testingPeer->neighbors[index].lastConnection;
//		BOOST_CHECK(previous <= current);
//	}
//
//	std::string output[2];
//
//}
//
//#include "VectorTimer.h"
//
//
//BOOST_AUTO_TEST_CASE(TestingVectorTimer)
//{
//
//	std::string inputString = "abc-1,0,0,0,0,0,0,0,0,0;";
//	int indexPosition = 1;
//	FixedVectorTimer<std::string> test(indexPosition);
//	test.FromString(inputString);
//
//	BOOST_CHECK_EQUAL(test.updateRepresented, "abc");
//
//	std::string testOuptut = test.ToString();
//	BOOST_CHECK_EQUAL(testOuptut, inputString);
//
//	test.UpdatePeerTimer(5);
//	BOOST_CHECK_EQUAL(test.ToString(), "abc-1,5,0,0,0,0,0,0,0,0;");
//
//	std::string difficultInputString = "a-,,,,,,,,,,";
//	test.FromString(difficultInputString);
//
//	BOOST_CHECK_EQUAL(test.updateRepresented, "a");
//	for (int index = 0; index < test.vectorTimer.size(); index++)
//	{
//		BOOST_CHECK_EQUAL(test.vectorTimer[index], 0);
//	}
//
//}
//
//
//#include "PeerSimulator.h"
//#include "DetermineUpdate.h"
//
//BOOST_AUTO_TEST_CASE(TestingPeerSimulator)
//{
//	std::string firstInputString = "a-1,0,0,0,0,0,0,0,0,0;";
//	std::string secondInputString ="b-0,1,0,0,0,0,0,0,0,0;";
//
//	FixedVectorTimer<std::string> test;
//	int testIndex = 5;
//	PeerSimulator simulator(testIndex, firstInputString);
//	test.FromString(secondInputString);
//	simulator.MergeUpdates(test);
//	
//	BOOST_CHECK_EQUAL(simulator.updater.ToString(), "ab-1,1,0,0,0,0,0,0,0,0;");
//
//}

//#include "BoundingBox.h"
//
//BOOST_AUTO_TEST_CASE(TestingBoundingBox)
//{
//	Engine::BoundingBox *boundingBox = new Engine::BoundingBox();
//	boundingBox->Expand(Point3D(5, 5, 5));
//	boundingBox->Expand(Point3D(0, 0, 0));
//	
//	Point3D o = Point3D(-1, -1, -1);
//	Point3D d = boundingBox->GetCentroid();
//	Ray testRay = Ray(o,d);
//	double t = INT_MAX;
//	double tMax = INT_MAX;
//	bool result = boundingBox->CheckIntersection(testRay, t, tMax);
//
//	BOOST_CHECK_EQUAL(result, true);
//}

#include "Triangle.h"
#include "TriangleVertex.h"

using namespace Engine;
BOOST_AUTO_TEST_CASE(TestingTrinagleClass)
{
	//need to test intersection with a triangle
	Point3D point1(10, 32.8858643, 89.2217865);
	Point3D point2(10, 24.9462795, 89.2217865);
	Point3D point3(10, 25.2625332, 88.5665131);

	TriangleVertex vertex1(point1);
	TriangleVertex vertex2(point2);
	TriangleVertex vertex3(point3);

	Triangle* currentTriangle = new Triangle(vertex1, vertex2, vertex3);

	Ray currentRay;
	currentRay.o = Point3D(0,0,0);
	currentRay.d = Point3D(10,27.6982269,89.0033569);

	ShadeRec rec;
	double tmin;
	tmin = INT_MAX;
	bool firstTestOutput = currentTriangle->hit(currentRay.o, currentRay.d, tmin, rec);
	

	BOOST_CHECK_EQUAL(true, firstTestOutput);

	/*tmin = INT_MAX;
	bool secondTestOutput = currentTriangle->NewTriangleHit(currentRay.o, currentRay.d, tmin, rec);
	BOOST_CHECK_EQUAL(true, secondTestOutput);*/

}


#include "Sampler.h"
#include "Jittered.h"
#include "Point2D.h"

BOOST_AUTO_TEST_CASE(TestingSampling)
{
	//Engine::Sampler* testSampler = new Engine::Jittered();

	//cout << testSampler->GetNumSamples() << endl;
	//testSampler->GenerateSamples();

	//for (int index = 0; index < testSampler->GetNumSamples(); index++)
	//{
	//	Point2D currentSample = 
	//	cout << (Point2D)testSampler->SampleUnitSquare()
	//}

}
#include "Jittered.h"

BOOST_AUTO_TEST_CASE(SamplingTest)
{
	Jittered * jitteredSampler = new Jittered(4, 4);

	jitteredSampler->GenerateSamples();

	for (int index = 0; index < 4 * 4; index ++)
	{
		Point2D currentSample = jitteredSampler->SampleUnitSquare();
		cout << currentSample.x << "---" << currentSample.y << endl;
	}

	jitteredSampler->MapSamplesToHemisphere(10);

	for (int index = 0; index < 4 * 4; index ++)
	{
		Point3D currentSample = jitteredSampler->SampleHemispherical();
		cout << currentSample.x << "--" << currentSample.y << "--" << currentSample.z << endl;
	}
}

#include "Octree.h"
#include "Scene.h"
#include "SceneFactory.h"
#include "RadiancePoint.h"

BOOST_AUTO_TEST_CASE(IrradianceCahceOctree)
{

	int sceneIndex = 2;
	Engine::Scene * currentScene = SceneFactory().GetScene(sceneIndex);
	Engine::Octree * currentOctree = new Octree(currentScene);

	float rayLength = 1;

	//added four points 
	//octree splitted
	Engine::RadiancePoint * test0Point = new RadiancePoint(Point3D(-100, -100, -100), rayLength);
	Engine::RadiancePoint * test1Point = new RadiancePoint(Point3D(100,100,100), rayLength);
	Engine::RadiancePoint * test2Point = new RadiancePoint(Point3D(50, -50, 10), rayLength);
	Engine::RadiancePoint * test3Point = new RadiancePoint(Point3D(100, 10, 20), rayLength);
	currentOctree->InsertPoint(test0Point);
	currentOctree->InsertPoint(test1Point);
	currentOctree->InsertPoint(test2Point);
	currentOctree->InsertPoint(test3Point);
	//checked ofr a specific point 
	BOOST_CHECK_EQUAL(true, currentOctree->CheckIfExist(Point3D(100, 100, 100)));

}

#include "IrradianceCache.h"
#include "TracerFactory.h"
BOOST_AUTO_TEST_CASE(IrradianceCalculations)
{
	int sceneIndex = 2;
	Tracer* testTracer = TracerFactory().GetTracer(2);
	Engine::Scene * currentScene = SceneFactory().GetScene(sceneIndex);
	IrradianceCache * irradianceCacheTest = new IrradianceCache(currentScene, testTracer);
}

/*
	--------------------------------------
					ending
	--------------------------------------
*/
BOOST_AUTO_TEST_CASE(TestingEnding)
{
	int test = 0;
	cin >> test;

}

